﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.AutomaticInterferenceVolumeCreation.CApAIVCManager
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using DnProcessSimulateCommands.AutomaticInterferenceVolumeCreation.Resources;
using DnProcessSimulateCommands.SweptVolume;
using EngineeringInternalExtension;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Resources;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Tecnomatix.Engineering;
using Tecnomatix.Engineering.Ui;
using Tecnomatix.Engineering.Ui.WPF;


namespace DnProcessSimulateCommands.AutomaticInterferenceVolumeCreation;

internal class CApAIVCManager
{
  private static string ACCURACY_VALUE = "Accuracy";
  private static string KEEP_NI_SW_OBJS = "KeepNonIntersectingSweptVolumeObjects";
  private static string INCLUDE_CABLES = "ShouldIncludeCables";
  private static string SHOW_CONFIRM_MSG = "ShowStopConfirmationMsg";
  private const int ACCURACY_DEFAULT_VALUE = 30;
  internal ResourceManager ResourceMgr;
  private System.Drawing.Image doneIcon;
  private System.Drawing.Image inProgressIcon;
  private CApAIVCAutomaticInterferenceVolumeCreationLogic internalLogic;
  private TxSimulationSnapshotDataEx m_simulationSnapshotData;

  internal CApAIVCManager(
    TxInterferenceVolume_MayProceedCalculation ivMayProceed,
    TxSweptVolume_MayProceedCalculation svMayProceed)
  {
    this.internalLogic = new CApAIVCAutomaticInterferenceVolumeCreationLogic();
    this.internalLogic.InterferenceVolumeCallback = ivMayProceed;
    this.internalLogic.SweptVolumeCallback = svMayProceed;
    this.internalLogic.SimulationInitialized += new CApSimulationHandler_SimulationInitializedEventHandler(this.internalLogic_SimulationInitialized);
    this.ResourceMgr = AIVCResources.ResourceManager;
    this.doneIcon = (System.Drawing.Image) AIVCResources.gray_check.ToBitmap();
    this.inProgressIcon = (System.Drawing.Image) AIVCResources.spinning_progress_16;
  }

  public List<DataGridItem> CreateItemsFromSelection(
    TxSelection selection,
    ADD_BUTTON_CLICK_TYPE type)
  {
    return this.CreateItem(this.ExtendItemsFromSelection(selection, type));
  }

  private TxObjectList ExtendItemsFromSelection(
    TxSelection selectedObjects,
    ADD_BUTTON_CLICK_TYPE type)
  {
    TxObjectList filteredItems1 = selectedObjects.GetFilteredItems((ITxTypeFilter) new TxTypeFilter(typeof (ITxCompoundOperation)));
    TxObjectList filteredItems2 = selectedObjects.GetFilteredItems((ITxTypeFilter) new TxTypeFilter(new Type[1]
    {
      typeof (ITxRoboticOrderedCompoundOperation)
    }));
    TxObjectList filteredItems3 = selectedObjects.GetFilteredItems((ITxTypeFilter) new TxTypeFilter(typeof (ITxRoboticProgram)));
    TxObjectList txObjectList = new TxObjectList();
    switch (type)
    {
      case ADD_BUTTON_CLICK_TYPE.ADD_PROGRAMS_AND_OPERATIONS:
        ((TxObjectList<ITxObject>) txObjectList).AddRange((TxObjectList<ITxObject>) this.GetProgramsOperationsGeneral(new CApAIVCManager.GetSpecificObjectsDelegate(CApAIVCManager.GetOperationsAndProgramsFromCompoundOperation), filteredItems1));
        ((TxObjectList<ITxObject>) txObjectList).AddRange((TxObjectList<ITxObject>) this.GetProgramsOperationsGeneral(new CApAIVCManager.GetSpecificObjectsDelegate(CApAIVCManager.GetOperationsAndProgramsFromRoboticOperation), filteredItems2));
        ((TxObjectList<ITxObject>) txObjectList).AddRange((TxObjectList<ITxObject>) this.GetProgramsOperationsGeneral(new CApAIVCManager.GetSpecificObjectsDelegate(CApAIVCManager.GetRoboticProgram), filteredItems3));
        break;
      case ADD_BUTTON_CLICK_TYPE.ADD_ROBOTIC_OPERATIONS:
        ((TxObjectList<ITxObject>) txObjectList).AddRange((TxObjectList<ITxObject>) this.GetProgramsOperationsGeneral(new CApAIVCManager.GetSpecificObjectsDelegate(CApAIVCManager.GetCORoboticOperationDescendants), filteredItems1));
        ((TxObjectList<ITxObject>) txObjectList).AddRange((TxObjectList<ITxObject>) this.GetProgramsOperationsGeneral(new CApAIVCManager.GetSpecificObjectsDelegate(CApAIVCManager.GetRoboticOperation), filteredItems2));
        break;
      case ADD_BUTTON_CLICK_TYPE.ADD_ROBOTIC_PROGRAMS:
        ((TxObjectList<ITxObject>) txObjectList).AddRange((TxObjectList<ITxObject>) this.GetProgramsOperationsGeneral(new CApAIVCManager.GetSpecificObjectsDelegate(CApAIVCManager.GetRoboticPrograms), filteredItems1));
        ((TxObjectList<ITxObject>) txObjectList).AddRange((TxObjectList<ITxObject>) this.GetProgramsOperationsGeneral(new CApAIVCManager.GetSpecificObjectsDelegate(CApAIVCManager.GetORRoboticPrograms), filteredItems2));
        ((TxObjectList<ITxObject>) txObjectList).AddRange((TxObjectList<ITxObject>) this.GetProgramsOperationsGeneral(new CApAIVCManager.GetSpecificObjectsDelegate(CApAIVCManager.GetRoboticProgram), filteredItems3));
        break;
    }
    return txObjectList;
  }

  public int GetAccuracy(TxWindow wnd)
  {
    return (int) CApAIVCManager.GetValueFromRegistry(wnd, CApAIVCManager.ACCURACY_VALUE, (object) 30);
  }

  public void SetAccuracy(TxWindow wnd, int acc)
  {
    CApAIVCManager.SetValueToRegistry(wnd, CApAIVCManager.ACCURACY_VALUE, (object) acc);
  }

  public bool GetShowConfirmMsg(TxWindow wnd)
  {
    return (bool) CApAIVCManager.GetValueFromRegistry(wnd, CApAIVCManager.SHOW_CONFIRM_MSG, (object) true);
  }

  public void SetShowConfirmMsg(TxWindow wnd, bool val)
  {
    CApAIVCManager.SetValueToRegistry(wnd, CApAIVCManager.SHOW_CONFIRM_MSG, (object) val);
  }

  public bool GetKeepNISweptVolumes(TxWindow wnd)
  {
    return (bool) CApAIVCManager.GetValueFromRegistry(wnd, CApAIVCManager.KEEP_NI_SW_OBJS, (object) true);
  }

  public bool GetIncludeCables(TxWindow wnd)
  {
    return (bool) CApAIVCManager.GetValueFromRegistry(wnd, CApAIVCManager.INCLUDE_CABLES, (object) true);
  }

  public void SetIncludeCables(TxWindow wnd, bool val)
  {
    CApAIVCManager.SetValueToRegistry(wnd, CApAIVCManager.INCLUDE_CABLES, (object) val);
  }

  public void SetKeepNISweptVolumes(TxWindow wnd, bool val)
  {
    CApAIVCManager.SetValueToRegistry(wnd, CApAIVCManager.KEEP_NI_SW_OBJS, (object) val);
  }

  public void Generate(
    ItemCollection objects,
    double accuracy,
    bool? keepNISV,
    bool? includeCables)
  {
    TxObjectList txObjectList = this.FilterValidObjectsOnly(objects);
    this.m_simulationSnapshotData = (TxSimulationSnapshotDataEx) null;
    CApAIVCAutomaticInterferenceVolumeCreationLogic internalLogic = this.internalLogic;
    TxObjectList inputVolumeHolders = txObjectList;
    double accuracy1 = accuracy;
    bool? nullable = keepNISV;
    bool flag1 = false;
    int num1 = nullable.GetValueOrDefault() == flag1 & nullable.HasValue ? 1 : 0;
    nullable = includeCables;
    bool flag2 = true;
    int num2 = nullable.GetValueOrDefault() == flag2 & nullable.HasValue ? 1 : 0;
    internalLogic.Generate(inputVolumeHolders, accuracy1, num1 != 0, num2 != 0);
    this.applySimulationSnapshot();
    this.m_simulationSnapshotData = (TxSimulationSnapshotDataEx) null;
  }

  public void StopGeneration(bool stopInvoked) => this.internalLogic.Abort(stopInvoked);

  public static BitmapImage GetImage(string uri) => new BitmapImage(new Uri(uri));

  public System.Drawing.Image DoneIcon => this.doneIcon;

  public System.Drawing.Image InProgressIcon => this.inProgressIcon;

  public event LowLevelStepDurationEventHandler LowLevelStepDuration
  {
    add => this.internalLogic.LowLevelStepDuration += value;
    remove => this.internalLogic.LowLevelStepDuration -= value;
  }

  public event LowLevelStepProgressEventHandler LowLevelStepProgress
  {
    add => this.internalLogic.LowLevelStepProgress += value;
    remove => this.internalLogic.LowLevelStepProgress -= value;
  }

  public event NextHighLevelStepStartedEventHandler NextHighLevelStep
  {
    add => this.internalLogic.NextHighLevelStep += value;
    remove => this.internalLogic.NextHighLevelStep -= value;
  }

  public event NextMidLevelStepStartedEventHandler NextMidLevelStep
  {
    add => this.internalLogic.NextMidLevelStep += value;
    remove => this.internalLogic.NextMidLevelStep -= value;
  }

  public event CApAIVCLogErrorEventHandler LogError
  {
    add => this.internalLogic.LogError += value;
    remove => this.internalLogic.LogError -= value;
  }

  private TxObjectList FilterValidObjectsOnly(ItemCollection objects)
  {
    TxObjectList txObjectList = new TxObjectList();
    foreach (DataGridItem dataGridItem in (IEnumerable) objects)
    {
      if (dataGridItem.ValidityIconToolTip == null)
        ((Collection<ITxObject>) txObjectList).Add(dataGridItem.OperationProgramObject);
    }
    return txObjectList;
  }

  private ValidityStatus IsValid(ITxObject obj)
  {
    using (new TxCallMessages.Collector((object) "CApAIVCManager.IsValidObject"))
    {
      ValidityStatus validityStatus = ValidityStatus.VALID;
      ITxRoboticProgram itxRoboticProgram = obj as ITxRoboticProgram;
      ITxRoboticOrderedCompoundOperation compoundOperation = obj as ITxRoboticOrderedCompoundOperation;
      ITxRoboticOperation roboticOperation = obj as ITxRoboticOperation;
      ITxObjectCollection objectCollection = obj as ITxObjectCollection;
      if (itxRoboticProgram != null && itxRoboticProgram.Count < 1)
        validityStatus = ValidityStatus.ROB_PROGRAM_EMPTY;
      if (compoundOperation != null)
      {
        if (compoundOperation.Robot == null)
          return ValidityStatus.OPERATION_ROBOT_NOT_ASSIGNED;
        if (!((ITxObject) compoundOperation).CanBeModified)
          validityStatus = ValidityStatus.OPERATION_TC_AUTHORING;
      }
      if (objectCollection != null && ((Collection<ITxObject>) objectCollection.GetAllDescendants((ITxTypeFilter) new TxTypeFilter(typeof (ITxRoboticLocationOperation)))).Count < 2)
        validityStatus = ValidityStatus.OPERATION_NOT_ENOUGH_LOCATIONS;
      return validityStatus;
    }
  }

  private List<DataGridItem> CreateItem(ITxObject obj)
  {
    TxObjectList objList = new TxObjectList();
    ((Collection<ITxObject>) objList).Add(obj);
    return this.CreateItem(objList);
  }

  private List<DataGridItem> CreateItem(TxObjectList objList)
  {
    List<DataGridItem> dataGridItemList = new List<DataGridItem>();
    foreach (ITxObject itxObject in (Collection<ITxObject>) objList)
    {
      string vitt = (string) null;
      ImageSource vi = TxImageManager.GetImageByKey("ExclamationMarkRed").ConvertTo<ImageSource>(new Size());
      switch (this.IsValid(itxObject))
      {
        case ValidityStatus.VALID:
          vi = TxImageManager.GetImageByKey("SuccessfulGreen").ConvertTo<ImageSource>(new Size());
          break;
        case ValidityStatus.OPERATION_ROBOT_NOT_ASSIGNED:
          vitt = this.ResourceMgr.GetString("AIVC_MISSING_ROBOT");
          break;
        case ValidityStatus.OPERATION_NOT_ENOUGH_LOCATIONS:
          vitt = this.ResourceMgr.GetString("AIVC_NOT_ENOUGH_LOCATIONS");
          break;
        case ValidityStatus.ROB_PROGRAM_EMPTY:
          vitt = this.ResourceMgr.GetString("AIVC_EMPTY_ROB_PROGRAM");
          break;
        case ValidityStatus.OPERATION_TC_AUTHORING:
          vitt = string.Join("\n", TxCallMessages.GetMessages());
          break;
      }
      string name = itxObject.Name;
      ImageSource objectImageSource = TxIconManager.the().GetObjectImageSource(itxObject);
      DataGridItem dataGridItem = new DataGridItem(vi, objectImageSource, name, itxObject, vitt);
      dataGridItemList.Add(dataGridItem);
    }
    return dataGridItemList;
  }

  private static TxObjectList GetCORoboticOperationDescendants(ITxObject compOp)
  {
    return !(compOp is ITxCompoundOperation compoundOperation) ? new TxObjectList() : ((ITxObjectCollection) compoundOperation).GetAllDescendants((ITxTypeFilter) new TxTypeFilter(typeof (ITxRoboticOrderedCompoundOperation)));
  }

  private static TxObjectList GetORRoboticPrograms(ITxObject oper)
  {
    return oper is ITxRoboticOrderedCompoundOperation compoundOperation && compoundOperation.Robot != null ? compoundOperation.Robot.RoboticPrograms : new TxObjectList();
  }

  private static TxObjectList GetRoboticPrograms(ITxObject compOp)
  {
    if (!(compOp is ITxCompoundOperation))
      return new TxObjectList();
    TxObjectList operationDescendants = CApAIVCManager.GetCORoboticOperationDescendants(compOp);
    TxObjectList txObjectList = new TxObjectList();
    foreach (ITxObject itxObject in (Collection<ITxObject>) operationDescendants)
    {
      ITxRoboticOrderedCompoundOperation compoundOperation = itxObject as ITxRoboticOrderedCompoundOperation;
      if (compoundOperation.Robot != null)
        ((Collection<ITxObject>) txObjectList).Add((ITxObject) compoundOperation.Robot);
    }
    TxObjectList roboticPrograms = new TxObjectList();
    foreach (ITxObject itxObject in (Collection<ITxObject>) txObjectList)
    {
      ITxRobot itxRobot = itxObject as ITxRobot;
      if (itxRobot.RoboticPrograms != null)
        ((TxObjectList<ITxObject>) roboticPrograms).AddRange((TxObjectList<ITxObject>) itxRobot.RoboticPrograms);
    }
    return roboticPrograms;
  }

  private static TxObjectList GetRoboticOperation(ITxObject robOper)
  {
    TxObjectList roboticOperation1 = new TxObjectList();
    if (robOper is ITxRoboticOperation roboticOperation2)
      ((Collection<ITxObject>) roboticOperation1).Add((ITxObject) roboticOperation2);
    return roboticOperation1;
  }

  private static TxObjectList GetOperationsAndProgramsFromCompoundOperation(ITxObject obj)
  {
    TxObjectList compoundOperation = new TxObjectList();
    ((TxObjectList<ITxObject>) compoundOperation).AddRange((TxObjectList<ITxObject>) CApAIVCManager.GetCORoboticOperationDescendants(obj));
    ((TxObjectList<ITxObject>) compoundOperation).AddRange((TxObjectList<ITxObject>) CApAIVCManager.GetRoboticPrograms(obj));
    return compoundOperation;
  }

  private static TxObjectList GetOperationsAndProgramsFromRoboticOperation(ITxObject obj)
  {
    TxObjectList roboticOperation = new TxObjectList();
    ((TxObjectList<ITxObject>) roboticOperation).AddRange((TxObjectList<ITxObject>) CApAIVCManager.GetRoboticOperation(obj));
    ((TxObjectList<ITxObject>) roboticOperation).AddRange((TxObjectList<ITxObject>) CApAIVCManager.GetORRoboticPrograms(obj));
    return roboticOperation;
  }

  private static TxObjectList GetRoboticProgram(ITxObject obj)
  {
    TxObjectList roboticProgram = new TxObjectList();
    if (obj is ITxRoboticProgram itxRoboticProgram)
      ((Collection<ITxObject>) roboticProgram).Add((ITxObject) itxRoboticProgram);
    return roboticProgram;
  }

  private TxObjectList GetProgramsOperationsGeneral(
    CApAIVCManager.GetSpecificObjectsDelegate func,
    TxObjectList objects)
  {
    TxObjectList operationsGeneral = new TxObjectList();
    foreach (ITxObject sourceObject in (Collection<ITxObject>) objects)
      ((TxObjectList<ITxObject>) operationsGeneral).AddRange((TxObjectList<ITxObject>) func(sourceObject));
    return operationsGeneral;
  }

  private static object GetValueFromRegistry(TxWindow wnd, string valueName, object defaultValue)
  {
    object valueFromRegistry = defaultValue;
    object obj = (object) null;
    TxWindowSettings.RestoreWindowValue(wnd, valueName, ref obj);
    if (obj != null)
    {
      bool result;
      valueFromRegistry = !bool.TryParse(obj as string, out result) ? obj : (object) result;
    }
    return valueFromRegistry;
  }

  private static void SetValueToRegistry(TxWindow wnd, string valueName, object theValue)
  {
    TxWindowSettings.StoreWindowValue(wnd, valueName, theValue);
  }

  private void internalLogic_SimulationInitialized(object sender, EventArgs e)
  {
    if (this.m_simulationSnapshotData != null)
      return;
    this.createSimulationSnapshot();
  }

  private void createSimulationSnapshot()
  {
    this.m_simulationSnapshotData = new TxPhysicalRootEx().CreateSimulationSnapshot();
  }

  private void applySimulationSnapshot()
  {
    if (this.m_simulationSnapshotData == null)
      return;
    new TxPhysicalRootEx().ApplySimulationSnapshot(this.m_simulationSnapshotData);
  }

  private delegate TxObjectList GetSpecificObjectsDelegate(ITxObject sourceObject);
}
